
#ifndef __APR_BUCKET_BRIGADE_H
#define __APR_BUCKET_BRIGADE_H

#include "../net/netgeneral.h"
#include <apr_pools.h>
#include <apr_buckets.h>
#include "APRRWMutex.h"

class APRBucketBrigade
{
   public:
      APRBucketBrigade(apr_pool_t *imp);
      ~APRBucketBrigade();
      void AddSocketBucket(apr_socket_t *tsock);
      void WriteEOS();
      apr_size_t WriteFile(const char *filename, apr_size_t start, apr_size_t end, int isbinary);
      apr_size_t Writef(const char *format, ...);
      apr_size_t Write(const char *data, apr_size_t numbytes);
      apr_size_t PackedWrite(const char *data, apr_size_t numbytes)
         { return Write(data, numbytes); }
      apr_size_t Read(char *data, apr_size_t numbytes);
      apr_size_t Delete(apr_size_t numbytes);
      apr_size_t Pop(char *data, int numbytes);
      int CanRead()
      {
         return (!((APR_BRIGADE_EMPTY(bucketbrgde)) ||
                  (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bucketbrgde)))));
      }
      void Close() { WriteEOS(); }
      int IsClosed()
         { return (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bucketbrgde))); }
      apr_size_t PackedSpaceRemaining()
         { return ((IsClosed()) ? 0 : (apr_size_t)-1); }
      apr_size_t RealLength()
      {
         apr_status_t status;
         apr_off_t offt;
         status = apr_brigade_length(bucketbrgde, 0, &offt);
         return (apr_size_t)offt;
      }
      int HasData() { return CanRead(); }
      apr_bucket_alloc_t *DirectlyGetBucketAllocator() { return bucketalloc; }
      apr_bucket_brigade *DirectlyGetBucketBrigade() { return bucketbrgde; }
      void AddBucketSize(apr_bucket *bucket) { csize += bucket->length; }
      int BufferToBucketBrigade(const char *buffer, size_t *length, size_t smallblock);
      int BucketBrigadeToBuffer(char **buffer, size_t *length);
      APRRWMutex *rwlock;
   private:
      apr_pool_t *mp;
      apr_bucket_alloc_t *bucketalloc;
      apr_bucket_brigade *bucketbrgde;
      apr_size_t csize;
};

#endif
